package com.example.jpa.crud.route;

import com.example.jpa.crud.service.JsonService;
import com.example.jpa.crud.service.SimpleCrudService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.util.MultiValueMap;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.RouterFunctions;
import org.springframework.web.servlet.function.ServerResponse;

import java.io.IOException;

@Deprecated
// @Configuration
public class SimpleCrudHandlerFunctions {

    private static final String API_PREFIX = "/api";

    private static final Logger log = LoggerFactory.getLogger(SimpleCrudHandlerFunctions.class);

    // @Autowired
    private SimpleCrudService simpleCrudService;

    // @Autowired
    private JsonService jsonService;

    @Bean
    public RouterFunction<ServerResponse> create() {
        return RouterFunctions.route().POST(API_PREFIX + "/{resource}",
                request -> {
                    log.info("create [{}] {}", request.method(), request.uri());
                    final String resource = request.pathVariable("resource");
                    byte[] data = new byte[0];
                    try {
                        data = request.body(byte[].class);
                    } catch (IOException e) {
                        log.error("create", e);
                    }
                    final Object object = simpleCrudService.create(resource, data);
                    final String json = jsonService.toJson(object);
                    return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(json);
                }
        ).build();
    }

    @Bean
    public RouterFunction<ServerResponse> findById() {
        return RouterFunctions.route().GET(API_PREFIX + "/{resource}/{id}",
                request -> {
                    log.info("findById: [{}] {}", request.method(), request.uri());
                    final String resource = request.pathVariable("resource");
                    final String id = request.pathVariable("id");
                    final Object object = simpleCrudService.findById(resource, id);
                    final String json = jsonService.toJson(object);
                    return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(json);
                }
        ).build();
    }

    @Bean
    public RouterFunction<ServerResponse> search() {
        return RouterFunctions.route().GET(API_PREFIX + "/{resource}",
                request -> {
                    log.info("search: [{}] {}", request.method(), request.uri());
                    final String resource = request.pathVariable("resource");
                    final MultiValueMap<String, String> parameterMap = request.params();
                    final Object object = simpleCrudService.search(resource, parameterMap);
                    final String json = jsonService.toJson(object);
                    return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(json);
                }
        ).build();
    }

    @Bean
    public RouterFunction<ServerResponse> updateById() {
        return RouterFunctions.route().PUT(API_PREFIX + "/{resource}/{id}",
                request -> {
                    log.info("updateById: [{}] {}", request.method(), request.uri());
                    final String resource = request.pathVariable("resource");
                    final String id = request.pathVariable("id");
                    byte[] data = new byte[0];
                    try {
                        data = request.body(byte[].class);
                    } catch (IOException e) {
                        log.error("updateById", e);
                    }
                    final Object object = simpleCrudService.updateById(resource, id, data);
                    final String json = jsonService.toJson(object);
                    return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(json);
                }
        ).build();
    }

    @Bean
    public RouterFunction<ServerResponse> deleteById() {
        return RouterFunctions.route().DELETE(API_PREFIX + "/{resource}/{id}",
                request -> {
                    log.info("deleteById: [{}] {}", request.method(), request.uri());
                    final String resource = request.pathVariable("resource");
                    final String id = request.pathVariable("id");
                    final Object object = simpleCrudService.deleteById(resource, id);
                    final String json = jsonService.toJson(object);
                    return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(json);
                }
        ).build();
    }

}
